#include "../include/state.h"
#include "../include/macro_report.h"
#include "../include/exception.h"
void State::createState()
{
	if(state_ptr==NULL)
		state_ptr=new State;
}

void State::checkCancel()
{
	if (is_cancel_copy)
	{
		occurCopyError(ERROR_TYPE_COPY_CANCEL,0);
		if(is_cancel_copy)
		{
			is_cancel_copy=false;
			if(is_cancel_other)
			{
				if(is_del_file)
					throw ExpCancel(ERROR_TYPE_CANCELED,true,true);
				else
					throw ExpCancel(ERROR_TYPE_CANCELED,true,false);
			}
			else
			{
				if(is_del_file)
					throw ExpCancel(ERROR_TYPE_CANCELED,false,true);
				else
					throw ExpCancel(ERROR_TYPE_CANCELED,false,false);
			}
		}
	}
}
void State::cancelCopy(bool is_cancel_other_,bool is_del_file_)
{
	is_cancel_other=is_cancel_other_;
	is_del_file=is_del_file_;
	event_for_watch.unlock();
	event_for_watch.ensureLock();
}
void State::continueCopy()
{
	is_cancel_copy=false;
	event_for_watch.unlock();
	event_for_watch.ensureLock();
}

void State::retry(uint32 is_retry_)
{
	is_retry=is_retry_;
	event_for_watch.unlock();
	event_for_watch.ensureLock();
}
void State::overwrite(bool is_over_write_)
{
	is_overwrite=is_over_write_;
	event_for_watch.unlock();
	event_for_watch.ensureLock();
}
void State::occurCopyError(uint32 error_type,uint32 error_code)
{
	reportError(error_type,error_code); 
	event_for_watch.unlock(); 
	event_for_watch.ensureLock();
	event_for_watch.lock();
}

void State::reportError(uint32 error_type,uint32 error_code)
{
	lock_for_error_report.lock();
	error_report.error_type=error_type;
	error_report.error_code=error_code;
	report_type=REPOTR_TYPE_ERROR;
	lock_for_error_report.unlock();
}
void State::reportBlockCount(uint32 prog_type,uint32 blk_count)
{
	prog_report.progress_type=prog_type;
	if(prog_type==PROG_COPYED_BLOCK_COUNT)
	{
		copyed_block+=blk_count;
		prog_report.progress_value=copyed_block;
	}
	else
		prog_report.progress_value=blk_count;
	report_type=REPORT_TYPE_PROGRESS;
	event_for_watch.unlock();
	event_for_watch.ensureLock();
	event_for_watch.lock();
}
void State::reportFileName(uint32 prog_type,const uint16* name,uint32 name_length)
{
	prog_report.progress_type=prog_type;
	prog_report.name=name;
	prog_report.name_length=name_length;
	report_type=REPORT_TYPE_PROGRESS;
	event_for_watch.unlock();
	event_for_watch.lock();
}

void State::errorReport(ErrorReport& report) const
{
	lock_for_error_report.lock();
	report.error_type=error_report.error_type;
	report.error_code=error_report.error_code;
	lock_for_error_report.unlock();
}
void State::progressReport(ProgressReport& report)
{
	report.name=prog_report.name;
	report.name_length=prog_report.name_length;
	report.progress_type=prog_report.progress_type;
	report.progress_value=prog_report.progress_value;
}

void State::stopWatching()
{
	event_for_watch.unlock();
}
State* State::state_ptr=NULL;
